
package com.shiku.imserver.common.http;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.http.common.Cookie;
import org.tio.http.common.HeaderName;
import org.tio.http.common.HeaderValue;
import org.tio.http.common.HttpResponseStatus;
import org.tio.utils.hutool.StrUtil;


public class HttpResponse
        extends HttpPacket {
    private static Logger log = LoggerFactory.getLogger(HttpResponse.class);

    private static final long serialVersionUID = -3512681144230291786L;

    public static final HttpResponse NULL_RESPONSE = new HttpResponse();


    public HttpResponse() {
    }


    public HttpResponse(HttpRequest request) {

        this();

        this.request = request;

        if (request == null) {

            return;

        }


        if (request.httpConfig != null && request.httpConfig.compatible1_0) {

            String connection = request.getConnection();

            switch (request.requestLine.version) {

                case "1.0":

                    if (StrUtil.equals(connection, "keep-alive")) {

                        addHeader(HeaderName.Connection, HeaderValue.Connection.keep_alive);

                        addHeader(HeaderName.Keep_Alive, HeaderValue.Keep_Alive.TIMEOUT_10_MAX_20);

                    }

                    return;

            }


            if (StrUtil.equals(connection, "close")) {
                ;
            }

        }

    }


    public HttpResponse(Map<HeaderName, HeaderValue> responseHeaders, byte[] body) {

        if (responseHeaders != null) {

            this.headers.putAll(responseHeaders);

        }

        setBody(body);

    }


    public void crossDomain() {

        addHeader(HeaderName.Access_Control_Allow_Origin, HeaderValue.from("*"));

        addHeader(HeaderName.Access_Control_Allow_Headers, HeaderValue.from("x-requested-with,content-type"));

    }


    public static HttpResponse cloneResponse(HttpRequest request, HttpResponse response) {

        HttpResponse cloneResponse = new HttpResponse(request);

        cloneResponse.setStatus(response.getStatus());

        cloneResponse.setBody(response.getBody());

        cloneResponse.setHasGzipped(response.isHasGzipped());

        cloneResponse.addHeaders(response.getHeaders());


        if (cloneResponse.getCookies() != null) {

            cloneResponse.getCookies().clear();

        }

        return cloneResponse;

    }


    public Map<HeaderName, HeaderValue> getHeaders() {

        return this.headers;

    }


    private HttpResponseStatus status = HttpResponseStatus.C200;


    private boolean isStaticRes = false;


    private HttpRequest request = null;
    private List<Cookie> cookies = null;

    private Map<HeaderName, HeaderValue> headers = new HashMap<>();

    private int headerByteCount = 2;


    private boolean hasGzipped = false;


    private String charset = "utf-8";


    private boolean skipIpStat = false;


    private boolean skipTokenStat = false;


    public void addHeader(HeaderName key, HeaderValue value) {

        this.headers.put(key, value);

        this.headerByteCount += key.bytes.length + value.bytes.length + 3;

    }


    public void addHeaders(Map<HeaderName, HeaderValue> headers) {

        if (headers != null) {

            Set<Map.Entry<HeaderName, HeaderValue>> set = headers.entrySet();

            for (Map.Entry<HeaderName, HeaderValue> entry : set) {

                addHeader(entry.getKey(), entry.getValue());

            }

        }

    }


    public HeaderValue getContentType() {

        return this.headers.get(HeaderName.Content_Type);

    }


    public boolean addCookie(Cookie cookie) {

        if (this.cookies == null) {


            this.cookies = new ArrayList<>();

        }


        return this.cookies.add(cookie);

    }


    public String getCharset() {

        return this.charset;

    }


    public List<Cookie> getCookies() {

        return this.cookies;

    }


    public HttpRequest getHttpRequest() {

        return this.request;

    }


    public HttpResponseStatus getStatus() {

        return this.status;

    }


    public boolean isStaticRes() {

        return this.isStaticRes;

    }


    @Override
    public String logstr() {

        String str = null;

        if (this.request != null) {

            str = "\r\n响应: 请求ID_" + this.request.getId() + "  " + this.request.getRequestLine().getPathAndQuery();

            str = str + "\r\n" + getHeaderString();

        } else {

            str = "\r\n响应\r\n" + this.status.getHeaderText();

        }

        return str;

    }


    public void setCharset(String charset) {

        this.charset = charset;

    }


    public void setCookies(List<Cookie> cookies) {

        this.cookies = cookies;

    }


    public void setHttpRequestPacket(HttpRequest request) {

        this.request = request;

    }


    public void setStaticRes(boolean isStaticRes) {

        this.isStaticRes = isStaticRes;

    }


    public void setStatus(HttpResponseStatus status) {

        this.status = status;

    }


    public boolean isHasGzipped() {

        return this.hasGzipped;

    }


    public void setHasGzipped(boolean hasGzipped) {

        this.hasGzipped = hasGzipped;

    }


    public boolean isSkipIpStat() {

        return this.skipIpStat;

    }


    public void setSkipIpStat(boolean skipIpStat) {

        this.skipIpStat = skipIpStat;

    }


    public boolean isSkipTokenStat() {

        return this.skipTokenStat;

    }


    public void setSkipTokenStat(boolean skipTokenStat) {

        this.skipTokenStat = skipTokenStat;

    }


    public HeaderValue getLastModified() {

        return getHeader(HeaderName.Last_Modified);

    }


    public HeaderValue getHeader(HeaderName name) {

        return this.headers.get(name);

    }


    public void setLastModified(HeaderValue lastModified) {

        if (lastModified != null) {

            addHeader(HeaderName.Last_Modified, lastModified);

        }

    }


    @Override
    public String toString() {

        return this.status.toString();

    }


    public int getHeaderByteCount() {

        return this.headerByteCount;

    }

}


